Indian Landmark Detection Using VGG-19¶

Importing libraries¶

In [ ]:
! pip install pandas
! pip install numpy
! pip install opencv-python
! pip install seaborn
! pip install tensorflow
! pip install scikit-learn
! pip install pickle
! pip install os
In [ ]:
import os
import cv2
import pickle
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

import keras
import tensorflow

from tensorflow.keras.models import Model
from tensorflow.keras.utils import plot_model
from tensorflow.keras.models import Sequential
from tensorflow.keras.applications import VGG19
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Input, Lambda, Dense, Flatten, Dropout, BatchNormalization, Activation

from sklearn.metrics import confusion_matrix, classification_report, accuracy_score, recall_score, precision_score, f1_score 

Defining data paths¶

In [ ]:
train_path = r'archive - Copy\Indian-monuments\images\train'
test_path = r'archive - Copy\Indian-monuments\images\test'

Converting image to pixels¶

In [ ]:
for folder in os.listdir(train_path):
    sub_path = train_path + "/" + folder
    
    print(folder)
    for i in range(2):
        temp_path = os.listdir(sub_path)[i]
        temp_path = sub_path + "/" + temp_path
        img = mpimg.imread(temp_path)
        imgplot = plt.imshow(img)
        plt.show()
Ajanta Caves
No description has been provided for this image
No description has been provided for this image
alai_darwaza
No description has been provided for this image
No description has been provided for this image
alai_minar
No description has been provided for this image
No description has been provided for this image
basilica_of_bom_jesus
No description has been provided for this image
No description has been provided for this image
Charar-E- Sharif
No description has been provided for this image
No description has been provided for this image
charminar
No description has been provided for this image
No description has been provided for this image
Chhota_Imambara
No description has been provided for this image
No description has been provided for this image
Ellora Caves
No description has been provided for this image
No description has been provided for this image
Fatehpur Sikri
No description has been provided for this image
No description has been provided for this image
Gateway of India
No description has been provided for this image
No description has been provided for this image
golden temple
No description has been provided for this image
No description has been provided for this image
hawa mahal pics
No description has been provided for this image
No description has been provided for this image
Humayun_s Tomb
No description has been provided for this image
No description has been provided for this image
India gate pics
No description has been provided for this image
No description has been provided for this image
iron_pillar
No description has been provided for this image
No description has been provided for this image
jamali_kamali_tomb
No description has been provided for this image
No description has been provided for this image
Khajuraho
No description has been provided for this image
No description has been provided for this image
lotus_temple
No description has been provided for this image
No description has been provided for this image
mysore_palace
No description has been provided for this image
No description has been provided for this image
qutub_minar
No description has been provided for this image
No description has been provided for this image
Sun Temple Konark
No description has been provided for this image
No description has been provided for this image
tajmahal
No description has been provided for this image
No description has been provided for this image
tanjavur temple
No description has been provided for this image
No description has been provided for this image
victoria memorial
No description has been provided for this image
No description has been provided for this image
In [ ]:
def imagearray(path, size):
    data = []
    for folder in os.listdir(path):
        sub_path=path+"/"+folder

        for img in os.listdir(sub_path):
            image_path=sub_path+"/"+img
            img_arr=cv2.imread(image_path)
            img_arr=cv2.resize(img_arr,size)
            
            data.append(img_arr)

    return data
In [ ]:
size = (250,250)
train = imagearray(train_path, size)
In [ ]:
test = imagearray(test_path, size)

Normalization¶

In [ ]:
x_train = np.array(train)
x_test = np.array(test)

x_train.shape,x_test.shape
Out[ ]:
((7909, 250, 250, 3), (1045, 250, 250, 3))
In [ ]:
x_train = x_train/255.0
x_test = x_test/255.0

Defining target variables¶

In [ ]:
def data_class(data_path, size, class_mode):
    datagen = ImageDataGenerator(rescale = 1./255)
    classes = datagen.flow_from_directory(data_path,
                                          target_size = size,
                                          batch_size = 32,
                                          class_mode = class_mode)
    return classes
In [ ]:
train_class = data_class(train_path, size, 'sparse')
test_class = data_class(test_path, size, 'sparse')
Found 7909 images belonging to 24 classes.
Found 1045 images belonging to 24 classes.
In [ ]:
y_train = train_class.classes
y_test = test_class.classes
print(train_class)
<keras.src.legacy.preprocessing.image.DirectoryIterator object at 0x00000246EDB82540>
In [ ]:
train_class.class_indices
Out[ ]:
{'Ajanta Caves': 0,
 'Charar-E- Sharif': 1,
 'Chhota_Imambara': 2,
 'Ellora Caves': 3,
 'Fatehpur Sikri': 4,
 'Gateway of India': 5,
 'Humayun_s Tomb': 6,
 'India gate pics': 7,
 'Khajuraho': 8,
 'Sun Temple Konark': 9,
 'alai_darwaza': 10,
 'alai_minar': 11,
 'basilica_of_bom_jesus': 12,
 'charminar': 13,
 'golden temple': 14,
 'hawa mahal pics': 15,
 'iron_pillar': 16,
 'jamali_kamali_tomb': 17,
 'lotus_temple': 18,
 'mysore_palace': 19,
 'qutub_minar': 20,
 'tajmahal': 21,
 'tanjavur temple': 22,
 'victoria memorial': 23}
In [ ]:
y_train.shape,y_test.shape,x_train.shape,x_test.shape
# y_val.shape
Out[ ]:
((7909,), (1045,), (7909, 250, 250, 3), (1045, 250, 250, 3))

VGG19 Model¶

In [ ]:
# vgg = VGG19(input_shape = (250, 250, 3), weights = 'imagenet', include_top = False)
In [ ]:
# for layer in vgg.layers:
#     layer.trainable = False

# x = Flatten()(vgg.output)
# prediction = Dense(24, activation='softmax')(x)

# model = Model(inputs=vgg.input, outputs=prediction)
# model.summary()
# model.compile(
#   loss='sparse_categorical_crossentropy',
#   optimizer="adam",
#   metrics=['accuracy']
# )
Model: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer (InputLayer)        │ (None, 250, 250, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block1_conv1 (Conv2D)           │ (None, 250, 250, 64)   │         1,792 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block1_conv2 (Conv2D)           │ (None, 250, 250, 64)   │        36,928 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block1_pool (MaxPooling2D)      │ (None, 125, 125, 64)   │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block2_conv1 (Conv2D)           │ (None, 125, 125, 128)  │        73,856 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block2_conv2 (Conv2D)           │ (None, 125, 125, 128)  │       147,584 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block2_pool (MaxPooling2D)      │ (None, 62, 62, 128)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_conv1 (Conv2D)           │ (None, 62, 62, 256)    │       295,168 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_conv2 (Conv2D)           │ (None, 62, 62, 256)    │       590,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_conv3 (Conv2D)           │ (None, 62, 62, 256)    │       590,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_conv4 (Conv2D)           │ (None, 62, 62, 256)    │       590,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_pool (MaxPooling2D)      │ (None, 31, 31, 256)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_conv1 (Conv2D)           │ (None, 31, 31, 512)    │     1,180,160 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_conv2 (Conv2D)           │ (None, 31, 31, 512)    │     2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_conv3 (Conv2D)           │ (None, 31, 31, 512)    │     2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_conv4 (Conv2D)           │ (None, 31, 31, 512)    │     2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_pool (MaxPooling2D)      │ (None, 15, 15, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_conv1 (Conv2D)           │ (None, 15, 15, 512)    │     2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_conv2 (Conv2D)           │ (None, 15, 15, 512)    │     2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_conv3 (Conv2D)           │ (None, 15, 15, 512)    │     2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_conv4 (Conv2D)           │ (None, 15, 15, 512)    │     2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_pool (MaxPooling2D)      │ (None, 7, 7, 512)      │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ flatten (Flatten)               │ (None, 25088)          │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense)                   │ (None, 24)             │       602,136 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 20,626,520 (78.68 MB)
 Trainable params: 602,136 (2.30 MB)
 Non-trainable params: 20,024,384 (76.39 MB)
In [ ]:
import tensorflow as tf
model = Sequential()

pretrained_model= tf.keras.applications.ResNet152(include_top=False,
                   input_shape=(250,250,3),
                   pooling='avg',classes=24,
                   weights='imagenet')
for layer in pretrained_model.layers:
        layer.trainable=False

model.add(pretrained_model)
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(24, activation='softmax'))
In [ ]:
early_stop = EarlyStopping(monitor = 'val_loss', mode='min', verbose = 1, patience = 5)
In [ ]:
history = model.fit(x_train,y_train, validation_data = (x_test,y_test), epochs = 10, callbacks=[early_stop], batch_size = 30,
                    shuffle=True)
Epoch 1/10
264/264 ━━━━━━━━━━━━━━━━━━━━ 3084s 11s/step - accuracy: 0.3604 - loss: 2.6060 - val_accuracy: 0.5254 - val_loss: 2.5025
Epoch 2/10
264/264 ━━━━━━━━━━━━━━━━━━━━ 2544s 10s/step - accuracy: 0.7235 - loss: 0.9685 - val_accuracy: 0.5943 - val_loss: 2.2280
Epoch 3/10
264/264 ━━━━━━━━━━━━━━━━━━━━ 2553s 10s/step - accuracy: 0.8286 - loss: 0.5631 - val_accuracy: 0.5780 - val_loss: 2.4538
Epoch 4/10
264/264 ━━━━━━━━━━━━━━━━━━━━ 2537s 10s/step - accuracy: 0.8853 - loss: 0.4026 - val_accuracy: 0.5952 - val_loss: 2.7145
Epoch 5/10
264/264 ━━━━━━━━━━━━━━━━━━━━ 2543s 10s/step - accuracy: 0.8982 - loss: 0.3809 - val_accuracy: 0.6220 - val_loss: 3.0336
Epoch 6/10
264/264 ━━━━━━━━━━━━━━━━━━━━ 2566s 10s/step - accuracy: 0.9137 - loss: 0.3285 - val_accuracy: 0.5990 - val_loss: 3.0443
Epoch 7/10
264/264 ━━━━━━━━━━━━━━━━━━━━ 2530s 10s/step - accuracy: 0.9101 - loss: 0.3349 - val_accuracy: 0.5809 - val_loss: 3.7339
Epoch 7: early stopping
In [ ]:
model.save("resnet.h5")
WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. 

Visualization¶

In [ ]:
plt.figure(figsize=(10, 8))
plt.plot(history.history['accuracy'], label='train acc')
plt.plot(history.history['val_accuracy'], label='val acc')
plt.legend()
plt.title('Accuracy')
plt.show()
No description has been provided for this image
In [ ]:
plt.figure(figsize=(10, 8))
plt.plot(history.history['loss'], label='train loss')
plt.plot(history.history['val_loss'], label='val loss')
plt.legend()
plt.title('Loss')
plt.show()
No description has been provided for this image

Model Evaluation¶

In [ ]:
model.evaluate(x_test, y_test, batch_size=32)
33/33 ━━━━━━━━━━━━━━━━━━━━ 315s 9s/step - accuracy: 0.5528 - loss: 4.5700
Out[ ]:
[3.712730646133423, 0.5808612704277039]
In [ ]:
y_pred = model.predict(x_test)
33/33 ━━━━━━━━━━━━━━━━━━━━ 313s 9s/step
In [ ]:
y_pred=np.argmax(y_pred,axis=1)
In [ ]:
print(classification_report(y_pred,y_test))
              precision    recall  f1-score   support

           0       0.97      1.00      0.98        30
           1       0.85      0.83      0.84        35
           2       0.47      0.25      0.33        28
           3       0.21      0.33      0.25        21
           4       0.52      0.69      0.59        32
           5       0.37      0.42      0.39        26
           6       0.33      0.93      0.49        29
           7       1.00      0.36      0.53        83
           8       0.47      1.00      0.64        21
           9       0.00      0.00      0.00         8
          10       0.10      0.13      0.11        31
          11       0.81      0.30      0.44        97
          12       0.17      0.67      0.27         9
          13       0.90      0.45      0.60        60
          14       0.78      0.48      0.59        67
          15       0.37      0.56      0.44        43
          16       0.81      0.91      0.86        89
          17       0.59      0.87      0.70        31
          18       0.23      0.50      0.32        14
          19       0.10      0.18      0.13        17
          20       0.97      0.50      0.66       135
          21       0.77      0.89      0.83        54
          22       0.82      0.86      0.84        43
          23       1.00      0.71      0.83        42

    accuracy                           0.58      1045
   macro avg       0.57      0.58      0.53      1045
weighted avg       0.72      0.58      0.60      1045

Confusion Matrix¶

In [ ]:
cm = confusion_matrix(y_pred,y_test)

plt.figure(figsize=(10, 8))
ax = plt.subplot()
sns.set(font_scale=2.0)
sns.heatmap(cm, annot=True, fmt='g', cmap="Blues", ax=ax); 

# labels, title and ticks
ax.set_xlabel('Predicted labels', fontsize=20);
ax.set_ylabel('True labels', fontsize=20); 
ax.set_title('Confusion Matrix', fontsize=20); 
No description has been provided for this image
In [ ]:
f1_score(y_test, y_pred, average='micro')
Out[ ]:
0.5808612440191387
In [ ]:
recall_score(y_test, y_pred, average='weighted')
Out[ ]:
0.5808612440191387
In [ ]:
precision_score(y_test, y_pred, average='micro')
Out[ ]:
0.5808612440191387

Saving Model¶

In [ ]:
model.save("resent152(1).h5")
WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`.